iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Software Development

從Servlet到Spring MVC系列 第 8

Day07 Servlet - Servlet Structure

  • 分享至 

  • xImage
  •  

前言

在介紹過Servlet的運作與生命週期後,今日我們來看看層層繼承與實作當中在做什麼吧!

0、創建module

(1) 創建module day07

請參考Day05創建module

(2) day07範例建立

創建HelloServlet

這一次我們有別於以往,我們繼承HttpServlet,並且按我們的需求override doGet方法

@WebServlet("/Hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.getWriter().println("Hello World!!!");
    }
}
訪問頁面

https://ithelp.ithome.com.tw/upload/images/20240922/20128084G46XEsJPPq.png

一、HelloServlet 繼承結構

我們可以從intellij查看繼承結構,在HelloServlet右鍵選擇Show Diagram
https://ithelp.ithome.com.tw/upload/images/20240922/20128084VxqzQ8KTcl.png
選擇以method展開,頁面左上角m
https://ithelp.ithome.com.tw/upload/images/20240922/20128084YYq8CSbbft.png
我們先從最左邊的兩個interface分別是

(1) ServletConfig

作為tomcat可以再初始化Servlet傳遞設定檔訊息的物件

(2) Servlet

container會調用service方法處理http請求與回應,init方法則是第一次調用該servlet或是設定loadonstartup時調用一次的方法,destory則是該生命週期結束時會調用一次的方法
記得我們前幾天都是直接implement Servlet介面的實作範例,而這邊提供兩個抽象方法繼承替我們解決複雜的工,讓我們最後再繼承HttpServlet時只需要關注我們要處理的Http Method請求

(3) GenericServlet

關注service以外的方法與基礎處理

  • 這邊實現了destroy空方法,讓我們下一個繼承的class有需要實現再override

  • init(ServletConfig config)幫我們把container傳遞給我們的配置訊息傳給成員變數,後面的繼承class可以方便調用,或透過getServletConfig()調用。

@Override
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

多了一個init()無參的空方法,並且在init(ServletConfig config)時會調用這個方法,目的在於後面的繼承class override這個init()時也可以被初始化

public void init() throws ServletException {}
  • 再次聲明service抽象方法,供後面繼承class實作
    @Override
      public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
    

(4) HttpServlet

關注service的實現。此處將ServletRequest、ServletResponse轉成子物件HttpServletRequest、HttpServletResponse,代表container收到http請求時實際是封裝成HttpServletRequest、HttpServletResponse,所以此處轉型並不會有問題。最後將他們交由overloading的方法去執行,其中再依http method交由doXXX方法,後面繼承class按需實作欲處理的http method 的doXXX

@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    HttpServletRequest request;
    HttpServletResponse response;

    if (!(req instanceof HttpServletRequest && res instanceof HttpServletResponse)) {
        throw new ServletException("non-HTTP request or response");
    }

    request = (HttpServletRequest) req;
    response = (HttpServletResponse) res;

    service(request, response);
}

若後面繼承的class為override doXXX則會被擋在父類調用getMethodNotSupportedCode回傳405

//以delete為例
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String protocol = req.getProtocol();
    String msg = lStrings.getString("http.method_delete_not_supported");
    resp.sendError(getMethodNotSupportedCode(protocol), msg);
}
private int getMethodNotSupportedCode(String protocol) {
    switch (protocol) {
    case "HTTP/0.9":
    case "HTTP/1.0":
        return HttpServletResponse.SC_BAD_REQUEST;
    default:
        return HttpServletResponse.SC_METHOD_NOT_ALLOWED;
    }
}

二、梳理http程式訪問流程

https://ithelp.ithome.com.tw/upload/images/20240922/201280846HzpHx3iIG.png

Reference


上一篇
Day06 Servlet - Servlet Life Cycle
下一篇
Day08 Servlet - ServletConfig and ServletContext
系列文
從Servlet到Spring MVC36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言